{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  K近邻"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 距离度量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import math\n",
    "from itertools import combinations"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- p = 1 曼哈顿距离\n",
    "- p = 2 欧氏距离\n",
    "- p = inf  闵式距离minkowski_distance "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def L(x, y, p=2):\n",
    "    # x1 = [1, 1], x2 = [5,1]\n",
    "    if len(x) == len(y) and len(x) > 1:\n",
    "        sum = 0\n",
    "        for i in range(len(x)):\n",
    "            sum += math.pow(abs(x[i] - y[i]), p)\n",
    "        return math.pow(sum, 1/p)\n",
    "    else:\n",
    "        return 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 课本例3.1\n",
    "x1 = [1, 1]\n",
    "x2 = [5, 1]\n",
    "x3 = [4, 4]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(4.0, '1-[5, 1]')\n",
      "(4.0, '1-[5, 1]')\n",
      "(3.7797631496846193, '1-[4, 4]')\n",
      "(3.5676213450081633, '1-[4, 4]')\n"
     ]
    }
   ],
   "source": [
    "# x1, x2\n",
    "for i in range(1, 5):\n",
    "    r = { '1-{}'.format(c):L(x1, c, p=i) for c in [x2, x3]}\n",
    "    print(min(zip(r.values(), r.keys())))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python实现，遍历所有数据点，找出n个距离最近的点的分类情况，少数服从多数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "from sklearn.datasets import load_iris\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "from collections import Counter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# data\n",
    "iris = load_iris()\n",
    "df = pd.DataFrame(iris.data, columns=iris.feature_names)\n",
    "df['label'] = iris.target\n",
    "df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']\n",
    "# data = np.array(df.iloc[:100, [0, 1, -1]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x205f88cb438>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x205f88cb470>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(df[:50]['sepal length'], df[:50]['sepal width'], label='0')\n",
    "plt.scatter(df[50:100]['sepal length'], df[50:100]['sepal width'], label='1')\n",
    "plt.xlabel('sepal length')\n",
    "plt.ylabel('sepal width')\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = np.array(df.iloc[:100, [0, 1, -1]])\n",
    "X, y = data[:,:-1], data[:,-1]\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "class KNN:\n",
    "    def __init__(self, X_train, y_train, n_neighbors=3, p=2):\n",
    "        \"\"\"\n",
    "        parameter: n_neighbors 临近点个数\n",
    "        parameter: p 距离度量\n",
    "        \"\"\"\n",
    "        self.n = n_neighbors\n",
    "        self.p = p\n",
    "        self.X_train = X_train\n",
    "        self.y_train = y_train\n",
    "    \n",
    "    def predict(self, X):\n",
    "        # 取出n个点\n",
    "        knn_list = []\n",
    "        for i in range(self.n):\n",
    "            dist = np.linalg.norm(X - self.X_train[i], ord=self.p)\n",
    "            knn_list.append((dist, self.y_train[i]))\n",
    "            \n",
    "        for i in range(self.n, len(self.X_train)):\n",
    "            max_index = knn_list.index(max(knn_list, key=lambda x: x[0]))\n",
    "            dist = np.linalg.norm(X - self.X_train[i], ord=self.p)\n",
    "            if knn_list[max_index][0] > dist:\n",
    "                knn_list[max_index] = (dist, self.y_train[i])\n",
    "                \n",
    "        # 统计\n",
    "        knn = [k[-1] for k in knn_list]\n",
    "        count_pairs = Counter(knn)\n",
    "        max_count = sorted(count_pairs, key=lambda x:x)[-1]\n",
    "        return max_count\n",
    "    \n",
    "    def score(self, X_test, y_test):\n",
    "        right_count = 0\n",
    "        n = 10\n",
    "        for X, y in zip(X_test, y_test):\n",
    "            label = self.predict(X)\n",
    "            if label == y:\n",
    "                right_count += 1\n",
    "        return right_count / len(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "clf = KNN(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "clf.score(X_test, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test Point: 1.0\n"
     ]
    }
   ],
   "source": [
    "test_point = [6.0, 3.0]\n",
    "print('Test Point: {}'.format(clf.predict(test_point)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x205f8dddf28>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYUAAAEKCAYAAAD9xUlFAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XucVXW9//HXx3ESTHRSsGQGwtvhoQIBjqKiqaEHRUoj\nM00z1Eekx5NlRUl6vKWpUWnqIzlYlhdEyUNYpmippHmBuAkqmnq8MKO/I1KgCBqMn98fa81m2M5l\nr7332nuttd/Px2MeM+u71/7O57v2g/mw1vp+1tfcHREREYCtqh2AiIgkh5KCiIjkKCmIiEiOkoKI\niOQoKYiISI6SgoiI5CgpiIhIjpKCiIjkKCmIiEjO1nH/AjOrAxYCre4+Pu+1w4C7gZfDptnufml3\n/fXt29cHDRoUQ6QiItm1aNGit9y9X0/7xZ4UgG8CK4Dtu3j90fxk0Z1BgwaxcOHCsgQmIlIrzOzV\nQvaL9fKRmTUBxwC/jPP3iIhIecR9T+Ea4HvAB93sc5CZLTOz+8xsn852MLNJZrbQzBauWrUqlkBF\nRCTGpGBm44E33X1RN7stBga6+zDgOmBOZzu5+3R3b3b35n79erwkJiIiRYrznsJo4HNmNg7oBWxv\nZre5+yntO7j72x1+vtfMfmFmfd39rRjjEpEE2bhxIy0tLbz33nvVDiUTevXqRVNTE/X19UW9P7ak\n4O5TgCmQm2X03Y4JIWz/BPB/7u5mtj/BmcvquGISkeRpaWmhT58+DBo0CDOrdjip5u6sXr2alpYW\ndt1116L6qMTsoy2Y2ZkA7j4NOB44y8w2ARuAE12r/ojUlPfee08JoUzMjJ122olS7r1WJCm4+zxg\nXvjztA7t1wPXVyIGkUqbs6SVqfc/z+trNtC/oTeTxw7muBGN1Q4rkZQQyqfUY1nxMwWRWjBnSStT\nZi9nw8Y2AFrXbGDK7OUASgySaHrMhUgMpt7/fC4htNuwsY2p9z9fpYhECqOkIBKD19dsiNQuhZsx\nAwYNgq22Cr7PmFFaf2vWrOEXv/hFUe+95pprWL9+fWkB5Lnwwgv585//3O0+8+bN4/HHHy/r722n\npCASg/4NvSO1S2FmzIBJk+DVV8E9+D5pUmmJIWlJ4dJLL+WII47odh8lBZGUmTx2ML3r67Zo611f\nx+Sxg6sUUTacfz7k/w1evz5oL9Z5553HSy+9xPDhw5k8eTJTp05lv/32Y9iwYVx00UUAvPvuuxxz\nzDF86lOfYsiQIdx5551ce+21vP766xx++OEcfvjhXfa/3Xbbce6557LPPvswZsyY3MygpUuXcsAB\nBzBs2DA+//nP889//hOAiRMnctdddwHBs94uuugiRo4cydChQ3nuued45ZVXmDZtGldffTXDhw/n\n0UcfLX7wnVBSEInBcSMauWLCUBobemNAY0NvrpgwVDeZS/Taa9HaC3HllVey++67s3TpUo488khe\neOEFFixYwNKlS1m0aBGPPPIIc+fOpX///jz11FM8/fTTHHXUUZxzzjn079+fhx9+mIcffrjL/t99\n912am5t55plnOPTQQ7nkkksAOPXUU7nqqqtYtmwZQ4cOzbXn69u3L4sXL+ass87iJz/5CYMGDeLM\nM8/k3HPPZenSpRxyyCHFD74Tmn0kEpPjRjQqCZTZwIHBJaPO2svhgQce4IEHHmDEiBEArFu3jhde\neIFDDjmE73znO3z/+99n/Pjxkf4Qb7XVVnzpS18C4JRTTmHChAmsXbuWNWvWcOihhwLw1a9+lS9+\n8Yudvn/ChAkA7LvvvsyePbuU4RVESUFEUuPyy4N7CB0vIW27bdBeDu7OlClT+PrXv/6h1xYvXsy9\n997LBRdcwJgxY7jwwguL+h1R6wi22WYbAOrq6ti0aVNRvzMKXT4SkdQ4+WSYPh0++UkwC75Pnx60\nF6tPnz688847AIwdO5abbrqJdevWAdDa2sqbb77J66+/zrbbbsspp5zC5MmTWbx48Yfe25UPPvgg\nd4/g9ttv5+CDD2aHHXbgYx/7WO5+wK233po7a4gac7npTEFEUuXkk0tLAvl22mknRo8ezZAhQzj6\n6KP58pe/zIEHHggEN4lvu+02XnzxRSZPnsxWW21FfX09N9xwAwCTJk3iqKOOyt1b6MxHP/pRFixY\nwGWXXcbOO+/MnXfeCcDNN9/MmWeeyfr169ltt9349a9/XXDMn/3sZzn++OO5++67ue6668p6X8HS\n9qih5uZm18prItmxYsUK9tprr2qHEZvtttsud+ZRKZ0dUzNb5O7NPb1Xl49ERCRHl49ERMpg1KhR\nvP/++1u03XrrrRU/SyiVkoKISBnMnz+/2iGUhS4fiYhIjpKCiIjk6PKR1DwthiOymc4UpKa1L4bT\numYDzubFcOYsaa12aFJBc+fOZfDgweyxxx5ceeWV1Q6nqpQUpKZpMRxpa2vj7LPP5r777uPZZ59l\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x205f8c69a58>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(df[:50]['sepal length'], df[:50]['sepal width'], label='0')\n",
    "plt.scatter(df[50:100]['sepal length'], df[50:100]['sepal width'], label='1')\n",
    "plt.plot(test_point[0], test_point[1], 'bo', label='test_point')\n",
    "plt.xlabel('sepal length')\n",
    "plt.ylabel('sepal width')\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# scikitlearn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "           metric_params=None, n_jobs=1, n_neighbors=5, p=2,\n",
       "           weights='uniform')"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "clf_sk = KNeighborsClassifier()\n",
    "clf_sk.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "clf_sk.score(X_test, y_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### sklearn.neighbors.KNeighborsClassifier\n",
    "\n",
    "- n_neighbors: 临近点个数\n",
    "- p: 距离度量\n",
    "- algorithm: 近邻算法，可选{'auto', 'ball_tree', 'kd_tree', 'brute'}\n",
    "- weights: 确定近邻的权重"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
